import { steelCategoryArr, ISteelPipe } from "../steelPipe";

/** 管道公称直径枚举
 *
 */
export enum PipeDiameter {
  "DN20" = "DN20",
  "DN25" = "DN25",
  "DN32" = "DN32",
  "DN40" = "DN40",
  "DN50" = "DN50",
  "DN70" = "DN70",
  "DN80" = "DN80",
  "DN100" = "DN100",
  "DN125" = "DN125",
  "DN150" = "DN150",
  "DN200" = "DN200",
  "DN250" = "DN250",
  "DN300" = "DN300",
  "DN350" = "DN350",
  "DN400" = "DN400",
}

/** 水流量单位枚举
 *
 */
export enum FlowUnit {
  "m3/h" = "m3/h",
  "l/s" = "l/s",
  "l/min" = "l/min",
}

interface IPipe {
  diameter: PipeDiameter;
  vMin: number;
  vMax: number;
}

interface IPipeExtend extends IPipe {
  flow: number;
  velocity: number;
  isValid: boolean;
  flowUnit: string;
}
interface ISteelPipeExtent extends ISteelPipe {
  v_current: number;
  flow_current: number;
  flowUnit: string;
}
/** 水管管径、流速集合。
 * 空调冷水管道的比摩阻宜控制在100~300Pa/m之间，同时，还必须考虑到管道内最大流速超过3m/s时，会明显加决对管道和阀门的冲刷腐蚀的情况。当管道的绝对粗糙度采用K=0.0005m时，管道水流速可选用。
 */
const pipeArr: Array<IPipe> = [
  {
    diameter: PipeDiameter.DN20,
    vMin: 0.12,
    vMax: 0.4,
  },
  {
    diameter: PipeDiameter.DN25,
    vMin: 0.1,
    vMax: 0.5,
  },
  {
    diameter: PipeDiameter.DN32,
    vMin: 0.5,
    vMax: 0.6,
  },
  {
    diameter: PipeDiameter.DN40,
    vMin: 0.5,
    vMax: 0.7,
  },
  {
    diameter: PipeDiameter.DN50,
    vMin: 0.5,
    vMax: 0.9,
  },
  {
    diameter: PipeDiameter.DN70,
    vMin: 0.6,
    vMax: 1.0,
  },
  {
    diameter: PipeDiameter.DN80,
    vMin: 0.7,
    vMax: 1.2,
  },
  {
    diameter: PipeDiameter.DN100,
    vMin: 0.8,
    vMax: 1.4,
  },
  {
    diameter: PipeDiameter.DN125,
    vMin: 0.9,
    vMax: 1.6,
  },
  {
    diameter: PipeDiameter.DN150,
    vMin: 1.0,
    vMax: 1.8,
  },
  {
    diameter: PipeDiameter.DN200,
    vMin: 1.2,
    vMax: 2.1,
  },
  {
    diameter: PipeDiameter.DN250,
    vMin: 1.4,
    vMax: 2.3,
  },
  {
    diameter: PipeDiameter.DN300,
    vMin: 1.6,
    vMax: 2.4,
  },
  {
    diameter: PipeDiameter.DN350,
    vMin: 1.8,
    vMax: 2.6,
  },
  {
    diameter: PipeDiameter.DN400,
    vMin: 1.9,
    vMax: 2.8,
  },
];

const diameter = (dn: string): number => {
  if (dn.indexOf("DN") >= 0) {
    return parseInt(dn.substring(2));
  }
  return 20;
};

/** 根据水流量选择合适的供水管管径。
 *  范围DN20~DN400
 * @param flow 水流量
 * @param flowUnit 水流量单位，可选参数
 * @returns 水管对象
 */
export const selectPipe = (flow: number, flowUnit = FlowUnit["m3/h"]) => {
  let fl: number;
  switch (flowUnit) {
    case FlowUnit["m3/h"]:
      fl = flow / 3600;
      break;
    case FlowUnit["l/s"]:
      fl = flow / 1000;
      break;
    case FlowUnit["l/min"]:
      fl = flow / 60000;
      break;
    default:
      fl = flow / 3600;
  }
  let piArr: IPipeExtend[] = [];
  let pipe: IPipe, pp: IPipeExtend;
  for (let i = 0; i < pipeArr.length; i++) {
    let di = diameter(pipeArr[i].diameter) / 1000;
    let ar = (Math.PI * di * di) / 4;
    let v = fl / ar;
    if (v >= pipeArr[i].vMin && v <= pipeArr[i].vMax) {
      pipe = pipeArr[i];
      pp = {
        ...pipe,
        flow,
        flowUnit: flowUnit,
        velocity: v,
        isValid: true,
      };
      piArr.push(pp);
      break;
    }
  }
  return piArr;
};

/** 根据水流量选择合适的供水管管径。
 *  范围DN20~DN800
 * @param flow  水流量
 * @param flowUnit 水流量单位，可选参数
 * @returns 水管对象
 */
export const selectSteelPipe = (flow: number, flowUnit = FlowUnit["m3/h"]) => {
  let fl: number;
  switch (flowUnit) {
    case FlowUnit["m3/h"]:
      fl = flow / 3600;
      break;
    case FlowUnit["l/s"]:
      fl = flow / 1000;
      break;
    case FlowUnit["l/min"]:
      fl = flow / 60000;
      break;
    default:
      // 彻底检测，详尽性检查
      const _exhaustiveCheck: never = flowUnit; //可对类型进行收窄操作
      fl = _exhaustiveCheck;
      break;
  }
  if (fl <= 0 || fl >= 5066 / 3600)
    throw new Error("Argument out Of range exception,value range:0~5066m3/h");
  const sel = steelCategoryArr.find(
    (e) =>
      fl >= parseInt(e.flow.split("~")[0]) / 3600 &&
      fl < parseInt(e.flow.split("~")[1]) / 3600
  );
  if (!sel) return;
  /** 水管内径 */
  const d = (sel.external - sel.thickness * 2) / 1000;
  /** 水管截面积 */
  const ar = (Math.PI * d * d) / 4;
  /** 当前流速 */
  const v_current = fl / ar;
  const result: ISteelPipeExtent = {
    ...sel,
    v_current,
    flow_current: flow,
    flowUnit,
  };
  return result;
};
